
package com.telrob.bytevm.instruct;

import java.util.List;

import com.telrob.bytevm.compile.Instruct;
import com.telrob.bytevm.compile.ReplaceCode;
import com.telrob.bytevm.utils.Define;
import com.telrob.bytevm.utils.ToolUtils;
import com.telrob.bytevm.vm.Register;

public class JMP implements Instruct {
	public boolean isPseudo(String opt) {
		return false;
	}
	@Override
	public boolean isComplie(String opt) {
		if("jmp".equals(opt.toLowerCase())) {
			return true;
		}else if("je".equals(opt.toLowerCase())) {
			return true;
		}else if("jne".equals(opt.toLowerCase())) {
			return true;
		}else if("jg".equals(opt.toLowerCase())) {
			return true;
		}else if("jng".equals(opt.toLowerCase())) {
			return true;
		}else if("jl".equals(opt.toLowerCase())) {
			return true;
		}else if("jnl".equals(opt.toLowerCase())) {
			return true;
		}
		return false;
	}

	@Override
	public byte[] complie(String line,String[] param,int curretIndex,List<ReplaceCode>labelReplace) {
		byte[]bb=new byte[5];
		
		String opt=param[0];
		if("jmp".equals(opt.toLowerCase())) {
			bb[0]=Define.JMP;
		}else if("je".equals(opt.toLowerCase())) {
			bb[0]=Define.JE;
		}else if("jne".equals(opt.toLowerCase())) {
			bb[0]=Define.JNE;
		}else if("jg".equals(opt.toLowerCase())) {
			bb[0]=Define.JG;
		}else if("jng".equals(opt.toLowerCase())) {
			bb[0]=Define.JNG;
		}else if("jl".equals(opt.toLowerCase())) {
			bb[0]=Define.JL;
		}else if("jnl".equals(opt.toLowerCase())) {
			bb[0]=Define.JNL;
		}
		String numStr=param[1];
		try {
			int number=ToolUtils.parseNum(numStr);
			bb[1]=(byte)(0xFF&(number>>0));
			bb[2]=(byte)(0xFF&(number>>8));
			bb[3]=(byte)(0xFF&(number>>16));
			bb[4]=(byte)(0xFF&(number>>24));
		}catch(Exception e) {
			bb[1]=0;
			bb[2]=0;
			bb[3]=0;
			bb[4]=0;
			ReplaceCode code=new ReplaceCode(numStr, curretIndex+1);
			labelReplace.add(code);
		}
		return bb;
	}
	public int isRun(byte opt) {
		if(Define.JMP==opt) {
			return 4;
		}else if(Define.JE==opt||Define.JNE==opt
				||Define.JG==opt||Define.JNG==opt||Define.JL==opt||Define.JNL==opt) {
			return 5;
		}
		return -1;
	}
	public void parseRun(Register R,byte opt,byte[]code) {
		if(opt==Define.JMP) {
			R.PC=ToolUtils.getInt(code, R.PC+1);
		}else if(opt==Define.JE) {
			if(R.CX==0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}else if(opt==Define.JNE) {
			if(R.CX!=0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}else if(opt==Define.JG) {
			if(R.CX>0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}else if(opt==Define.JNG) {
			if(R.CX<=0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}else if(opt==Define.JL) {
			if(R.CX<0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}else if(opt==Define.JNL) {
			if(R.CX>=0) {
				R.PC=ToolUtils.getInt(code, R.PC+1);
			}else {
				R.PC=R.PC+isRun(opt);
			}
		}
	}

}
